guint fullscreen : 1;
guint tiled : 1;
+ guint drag_possible : 1;
+
+ gint button_press_x;
+ gint button_press_y;
+ guint32 button_press_time;
};
enum {
GdkEventKey *event);
static gint gtk_window_button_press_event (GtkWidget *widget,
GdkEventButton *event);
+static gint gtk_window_button_release_event (GtkWidget *widget,
+ GdkEventButton *event);
+static gint gtk_window_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event);
static gint gtk_window_focus_in_event (GtkWidget *widget,
GdkEventFocus *event);
static gint gtk_window_focus_out_event (GtkWidget *widget,
widget_class->key_release_event = gtk_window_key_release_event;
widget_class->focus_in_event = gtk_window_focus_in_event;
widget_class->button_press_event = gtk_window_button_press_event;
+ widget_class->button_release_event = gtk_window_button_release_event;
+ widget_class->motion_notify_event = gtk_window_motion_notify_event;
widget_class->focus_out_event = gtk_window_focus_out_event;
widget_class->focus = gtk_window_focus;
widget_class->move_focus = gtk_window_move_focus;
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_BUTTON_MOTION_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
return GTK_WINDOW_REGION_CONTENT;
}
+static inline gboolean
+in_double_click_range (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
+ gint double_click_time;
+ gint double_click_distance;
+
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-double-click-time", &double_click_time,
+ "gtk-double-click-distance", &double_click_distance,
+ NULL);
+
+ if (event->time < priv->button_press_time + double_click_time &&
+ ABS (event->x_root - priv->button_press_x) <= double_click_distance &&
+ ABS (event->y_root - priv->button_press_y) <= double_click_distance)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gint
+gtk_window_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
+ GtkWidget *src;
+ gboolean window_drag;
+
+ if (!priv->drag_possible)
+ return FALSE;
+
+ gdk_window_get_user_data (event->window, (gpointer *)&src);
+ if (src && src != widget)
+ {
+ gtk_widget_style_get (GTK_WIDGET (src),
+ "window-dragging", &window_drag,
+ NULL);
+ if (!window_drag)
+ {
+ priv->drag_possible = FALSE;
+ return FALSE;
+ }
+ }
+
+ if (!in_double_click_range (widget, (GdkEventButton *)event))
+ {
+ gdk_window_begin_move_drag_for_device (gtk_widget_get_window (widget),
+ gdk_event_get_device ((GdkEvent *)event),
+ GDK_BUTTON_PRIMARY,
+ event->x_root,
+ event->y_root,
+ event->time);
+ priv->drag_possible = FALSE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gint
+gtk_window_button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkWindow *window = GTK_WINDOW (widget);
+ GtkWindowPrivate *priv = window->priv;
+
+ priv->drag_possible = FALSE;
+
+ return FALSE;
+}
+
static gint
gtk_window_button_press_event (GtkWidget *widget,
GdkEventButton *event)
GtkWindowPrivate *priv = window->priv;
GdkWindowEdge edge;
GdkWindow *gdk_window;
+ gint x, y;
+ GtkWidget *src;
+ GtkWindowRegion region;
+ gboolean window_drag = FALSE;
gdk_window = gtk_widget_get_window (widget);
+ /* We do our own double-click detection, so we ignore
+ * GDK_2BUTTON_PRESS and GDK_3BUTTON_PRESS events
+ */
+ if (event->type != GDK_BUTTON_PRESS)
+ return FALSE;
+
+ if (priv->fullscreen)
+ return FALSE;
+
if (event->window == priv->grip_window)
{
if (get_drag_edge (widget, &edge))
return TRUE;
}
- else if (!priv->fullscreen)
+
+ gdk_window_get_user_data (event->window, (gpointer *)&src);
+ if (src && src != widget)
{
- gint x, y;
- GtkWidget *src;
- GtkWindowRegion region;
+ gtk_widget_style_get (GTK_WIDGET (src),
+ "window-dragging", &window_drag,
+ NULL);
+ gtk_widget_translate_coordinates (src, widget, event->x, event->y, &x, &y);
+ }
+ else
+ {
+ x = event->x;
+ y = event->y;
+ }
- gdk_window_get_user_data (event->window, (gpointer *)&src);
- if (src && src != widget)
+ region = get_active_region_type (window, (GdkEventAny*)event, x, y);
+
+ if (event->button == GDK_BUTTON_PRIMARY)
+ {
+ if (in_double_click_range (widget, event))
{
- gtk_widget_translate_coordinates (src, widget, event->x, event->y, &x, &y);
+ switch (region)
+ {
+ case GTK_WINDOW_REGION_CONTENT:
+ if (!window_drag) /* do nothing */
+ break;
+ /* fall thru */
+ case GTK_WINDOW_REGION_TITLE:
+ _gtk_window_toggle_maximized (window);
+ return TRUE;
+ default:
+ break;
+ }
}
else
{
- x = event->x;
- y = event->y;
- }
- region = get_active_region_type (window, (GdkEventAny*)event, x, y);
-
- if (event->type == GDK_BUTTON_PRESS)
- {
- if (event->button == GDK_BUTTON_PRIMARY)
+ switch (region)
{
- switch (region)
- {
- case GTK_WINDOW_REGION_CONTENT:
- /* do nothing */
- break;
- case GTK_WINDOW_REGION_TITLE:
- case GTK_WINDOW_REGION_EDGE:
- gdk_window_begin_move_drag_for_device (gdk_window,
- gdk_event_get_device ((GdkEvent *) event),
- event->button,
- event->x_root,
- event->y_root,
- event->time);
- return TRUE;
+ case GTK_WINDOW_REGION_CONTENT:
+ if (!window_drag)
+ break;
+ /* fall thru */
+
+ case GTK_WINDOW_REGION_TITLE:
+ case GTK_WINDOW_REGION_EDGE:
+ priv->drag_possible = TRUE;
+ priv->button_press_x = event->x_root;
+ priv->button_press_y = event->y_root;
+ priv->button_press_time = event->time;
+ return TRUE;
- default:
- if (!priv->maximized)
- {
- gdk_window_begin_resize_drag_for_device (gdk_window,
- (GdkWindowEdge)region,
- gdk_event_get_device ((GdkEvent *) event),
- event->button,
- event->x_root,
- event->y_root,
- event->time);
- return TRUE;
- }
- break;
- }
- }
- else if (event->button == GDK_BUTTON_SECONDARY)
- {
- if (region == GTK_WINDOW_REGION_TITLE)
+ default:
+ if (!priv->maximized)
{
- gtk_window_do_popup (window, event);
- return TRUE;
- }
- }
- else if (event->button == GDK_BUTTON_MIDDLE)
- {
- if (region == GTK_WINDOW_REGION_TITLE)
- {
- gdk_window_lower (gdk_window);
+ gdk_window_begin_resize_drag_for_device (gdk_window,
+ (GdkWindowEdge)region,
+ gdk_event_get_device ((GdkEvent *) event),
+ event->button,
+ event->x_root,
+ event->y_root,
+ event->time);
return TRUE;
}
+ break;
}
}
- else if (event->type == GDK_2BUTTON_PRESS)
+ }
+ else if (event->button == GDK_BUTTON_SECONDARY)
+ {
+ if (region == GTK_WINDOW_REGION_TITLE)
{
- if (region == GTK_WINDOW_REGION_TITLE)
- {
- _gtk_window_toggle_maximized (window);
- return TRUE;
- }
+ gtk_window_do_popup (window, event);
+ return TRUE;
+ }
+ }
+ else if (event->button == GDK_BUTTON_MIDDLE)
+ {
+ if (region == GTK_WINDOW_REGION_TITLE)
+ {
+ gdk_window_lower (gdk_window);
+ return TRUE;
}
}
gtk_widget_queue_draw (widget);
}
-gboolean
-_gtk_window_handle_button_press_for_widget (GtkWidget *widget,
- GdkEventButton *event)
-{
- gboolean window_drag = FALSE;
- GtkWindow *window;
-
- gtk_widget_style_get (GTK_WIDGET (widget),
- "window-dragging", &window_drag,
- NULL);
-
- if (!window_drag)
- return FALSE;
-
- if (event->button != GDK_BUTTON_PRIMARY)
- return FALSE;
-
- window = GTK_WINDOW (gtk_widget_get_toplevel (widget));
-
- switch (event->type)
- {
- case GDK_BUTTON_PRESS:
- gtk_window_begin_move_drag (window,
- event->button,
- event->x_root,
- event->y_root,
- event->time);
- return TRUE;
-
- case GDK_2BUTTON_PRESS:
- _gtk_window_toggle_maximized (window);
- return TRUE;
-
- default:
- break;
- }
-
- return FALSE;
-}
-
void
_gtk_window_get_shadow_width (GtkWindow *window,
GtkBorder *border)